﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NoDriverPrintHelperV1d0.Entity
{
    /// <summary>
    /// 数据类型转换
    /// </summary>
    public class DataFormatTransformV1d0
    {
        public const Byte ASCII_0 = 48;
        public const Byte ASCII_9 = 57;
        public const Byte ASCII_A = 65;
        public const Byte ASCII_F = 70;
        public const Byte ASCII_Z = 90;
        public const Byte ASCII_a = 97;
        public const Byte ASCII_f = 102;
        public const Byte ASCII_z = 122;

        /// <summary>
        /// 字节转换为字符串
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static String ByteToHexChar(Byte val)
        {
            return val.ToString("X2");
        }

        /// <summary>
        /// 字节转换为字符串
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static String ByteToBitString(Byte val)
        {
            if (val == 0)
            {
                return "00000000";
            }
            if (val == 255)
            {
                return "11111111";
            }

            String ret = String.Empty;
            Int32 bitval = 0;
            for (int bitidx = 7; bitidx > -1; --bitidx)
            {
                bitval = val & (1 << bitidx);
                if (bitval > 0)
                {
                    ret = ret + "1";
                }
                else
                {
                    ret = ret + "0";
                }
            }
            return ret;
        }

        /// <summary>
        /// 2个HEX字符转换为1个字节数组
        /// </summary>
        /// <param name="hexstr">"A1"</param>
        /// <param name="bytes">161</param>
        /// <returns></returns>
        public static Boolean HexStringToByte(String hexstr, out Byte byteval)
        {
            byteval = 0;
            if (hexstr.Length != 2)
            {
                return false;
            }

            byteval = Convert.ToByte(hexstr, 16);
            return true;
        }

        /// <summary>
        /// HEX字符串转换为字节数组
        /// </summary>
        /// <param name="hexstr"></param>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Boolean HexStringToBytes(String hexstr, out Byte[] bytes)
        {
            bytes = null;
            if ((hexstr == null) || (hexstr.Length < 2))
            {
                return false;
            }

            if (hexstr.Length % 2 == 1)
            {
                return false;
            }
            int bytelen = hexstr.Length / 2;
            if (bytelen < 1)
            {
                return false;
            }
            bytes = new Byte[bytelen];

            String curbytestr = String.Empty;
            for (int bidx = 0; bidx < bytelen; bidx++)
            {
                curbytestr = hexstr.Substring(bidx * 2, 2);
                //数字的进制，它必须是 2、8、10和16.
                bytes[bidx] = Convert.ToByte(curbytestr, 16);
            }

            if (bytes == null || bytes.Length < 1)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// HEX字符串转换为字节数组
        /// </summary>
        /// <param name="hexstr"></param>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Boolean HexStringToBytesWithSplitter(String hexstr, out Byte[] bytes)
        {
            bytes = null;

            if (hexstr == null || hexstr.Length < 2)
            {
                return false;
            }
            int charidx = 0;
            StringBuilder strbuild = new StringBuilder(hexstr.Length);
            //对每个字符进行判断,过滤非法字符
            while (charidx < hexstr.Length)
            {
                //A-65, F-70,a-97,f-102, 0-48 9-57

                if ((hexstr[charidx] >= DataFormatTransformV1d0.ASCII_0 && hexstr[charidx] <= DataFormatTransformV1d0.ASCII_9) ||
                    (hexstr[charidx] >= DataFormatTransformV1d0.ASCII_A && hexstr[charidx] <= DataFormatTransformV1d0.ASCII_F) ||
                    (hexstr[charidx] >= DataFormatTransformV1d0.ASCII_a && hexstr[charidx] <= DataFormatTransformV1d0.ASCII_f))
                {
                    strbuild.Append(hexstr[charidx]);
                }

                charidx++;
            }

            String purehexstr = strbuild.ToString();
            return HexStringToBytes(purehexstr, out bytes);
        }

        /// <summary>
        /// 字节数组转换为字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static String BytesToHexString(Byte[] bytes)
        {
            if (bytes == null || bytes.Length < 1)
            {
                return String.Empty;
            }

            StringBuilder str = new StringBuilder(bytes.Length * 2);
            for (int i = 0; i < bytes.Length; i++)
            {
                str.Append(bytes[i].ToString("X2"));
            }

            return str.ToString();
        }


        /// <summary>
        /// 字节数组转换为字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="start">待转换的首个字节下标</param>
        /// <param name="len"></param>
        /// <param name="eachlinebytes">每隔多少字节,就插入一个换行符.0表示不换行</param>
        /// <returns></returns>
        public static String BytesToHexString(Byte[] bytes, Int32 start, Int32 len, Int32 eachlinebytes)
        {
            if (bytes == null || bytes.Length < 1 || start < 0 || len < 1 || start + len > bytes.Length)
            {
                return String.Empty;
            }

            Int32 curlinebytes = 0;
            StringBuilder str = new StringBuilder(bytes.Length * 2);
            for (int i = 0; i < len; i++)
            {
                str.Append(bytes[i + start].ToString("X2"));
                if (eachlinebytes > 0)
                {
                    curlinebytes++;
                    if (curlinebytes >= eachlinebytes)
                    {
                        str.Append(Environment.NewLine);
                        curlinebytes = 0;
                    }
                }
            }

            return str.ToString();
        }


        /// <summary>
        /// 字节数组转换为带间隔符的字符串,显示用
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="start">待转换的首个字节下标</param>
        /// <param name="len"></param>
        /// <param name="splitter"></param>
        /// <param name="eachlinebytes">每隔多少字节,就插入一个换行符.0表示不换行</param>
        /// <returns></returns>
        public static String BytesToHexString(Byte[] bytes, Int32 start, Int32 len, Char splitter, Int32 eachlinebytes)
        {
            if (bytes == null || bytes.Length < 1 || start < 0 || len < 1 || start + len > bytes.Length)
            {
                return String.Empty;
            }

            Int32 curlinebytes = 0;
            StringBuilder str = new StringBuilder(bytes.Length * 2);
            for (int i = 0; i < bytes.Length; i++)
            {
                str.Append(bytes[i + start].ToString("X2"));
                if ((Byte)(splitter) != 0)
                {
                    str.Append(splitter);
                }

                if (eachlinebytes > 0)
                {
                    curlinebytes++;
                    if (curlinebytes >= eachlinebytes)
                    {
                        str.Append(Environment.NewLine);
                        curlinebytes = 0;
                    }
                }
            }

            str.Remove(str.Length - 1, 1);
            return str.ToString();
        }

        /// <summary>
        /// 字节数组转换为ASCII字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static String BytesToString(Byte[] bytes)
        {
            String ret = Encoding.Default.GetString(bytes);
            return ret;
        }

        /// <summary>
        /// 1个字节的BCD转换为HEX
        /// 0x12->12
        /// </summary>
        /// <param name="bcd">BCD字节</param>
        /// <returns>Int32</returns>
        public static Byte ByteBCDToHex(Byte bcd)
        {
            Byte result = (Byte)(bcd & 0x0F); //个位
            bcd >>= 4;
            result += (Byte)(bcd * 10);       //十位
            return result;            //返回结果
        }

        /// <summary>
        /// 把数组里的每个字节,都从HEX 转换为BCD
        /// </summary> 
        /// <returns></returns>
        public static Boolean ByteArrayHexToBCD(Byte[] hexbytes, Int32 hexstart, Byte[] bcdbytes, Int32 bcdstart, Int32 len)
        {
            if (hexbytes == null || bcdbytes == null ||
                hexbytes.Length < 1 || bcdbytes.Length < 1 ||
                hexstart < 0 || bcdstart < 0 ||
                hexstart + len > hexbytes.Length ||
                bcdstart + len > bcdbytes.Length)
            {
                return false;
            }

            for (Int32 idx = 0; idx < len; ++idx)
            {
                bcdbytes[bcdstart + idx] = ByteHexToBCD(hexbytes[hexstart + idx]);
            }
            return true;
        }

        /// <summary>
        /// 把数组里的每个字节,都从BCD转换为HEX 
        /// </summary> 
        /// <returns></returns>
        public static Boolean ByteArrayBCDToHex(Byte[] bcdbytes, Int32 bcdstart, Byte[] hexbytes, Int32 hexstart, Int32 len)
        {
            if (hexbytes == null || bcdbytes == null ||
                hexbytes.Length < 1 || bcdbytes.Length < 1 ||
                hexstart < 0 || bcdstart < 0 ||
                hexstart + len > hexbytes.Length ||
                bcdstart + len > bcdbytes.Length)
            {
                return false;
            }

            for (Int32 idx = 0; idx < len; ++idx)
            {
                hexbytes[hexstart + idx] = ByteBCDToHex(bcdbytes[bcdstart + idx]);
            }
            return true;
        }

        /// <summary>
        /// 1个字节的HEX转换为BCD
        /// 64->0x64
        /// </summary>
        /// <param name="bcd">BCD字节</param>
        /// <returns>Int32</returns>
        public static Byte ByteHexToBCD(Byte val)
        {
            //如果超过99,则转换99
            if (val > 99)
            {
                return 0x99;
            }
            Byte lowval = (Byte)(val % 10);//个位
            Byte highval = (Byte)((val / 10) % 10);//十位
            Byte ret = (Byte)(lowval + (highval << 4));
            return ret;
        }

        /// <summary>
        /// ASCII字符串转换为字节数组
        /// </summary>
        /// <param name="asciistr"></param>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Boolean StringToBytes(String asciistr, out Byte[] bytes)
        {
            bytes = Encoding.Default.GetBytes(asciistr);
            if (bytes == null || bytes.Length < 1)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Boolean 转换为 Int32 
        /// </summary>
        /// <param name="bl"></param>
        /// <returns></returns>
        public static Int32 BooleanToInt32(Boolean bl)
        {
            return bl ? 1 : 0;
        }

        /// <summary>
        /// Boolean 转换为 Int32 的字符串
        /// </summary>
        /// <param name="bl"></param>
        /// <returns></returns>
        public static String BooleanToInt32String(Boolean bl)
        {
            return bl ? "1" : "0";
        }

        /// <summary>
        /// Int32  转换为 Boolean
        /// </summary>
        /// <param name="intval"></param>
        /// <returns></returns>
        public static Boolean Int32ToBoolean(Int32 intval)
        {
            return (intval == 0) ? false : true;
        }

        /// <summary>
        /// Int32 的字符串  转换为 Boolean 
        /// </summary>
        /// <param name="intstr"></param>
        /// <returns></returns>
        public static Boolean Int32StringToBoolean(String intstr)
        {
            if (intstr.Length < 1)
            {
                return false;
            }
            return (intstr[0] == '0') ? false : true;
        }

        /// <summary>
        /// 各种枚举值转换为Int32String
        /// </summary>
        /// <param name="bl"></param>
        /// <returns></returns>
        public static String Int32ToString(Int32 enumval)
        {
            return enumval.ToString();
        }

        /// <summary>
        /// 使用指定间隔符,把字符串分割为多个子串,合并为List
        /// </summary>
        /// <param name="rawdata"></param>
        /// <param name="splitter"></param>
        /// <param name="strlist"></param>
        /// <returns></returns>
        public static Boolean StringToIntArray(String rawdata, char splitter, ref Int32[] intarray)
        {
            List<String> strlst = null;
            Boolean bl = StringToList(rawdata, splitter, ref strlst);
            if (!bl)
            {
                return false;
            }

            List<int> intlist = new List<int>();
            Int32 val;
            for (int i = 0; i < strlst.Count; i++)
            {
                bl = Int32.TryParse(strlst[i], out val);
                if (bl)
                {
                    intlist.Add(val);
                }
            }

            if (intlist.Count < 1)
            {
                return false;
            }

            intarray = intlist.ToArray();
            return true;
        }


        /// <summary>
        /// 使用指定间隔符,把List合并为一个字符串
        /// </summary>
        /// <param name="strlist"></param>
        /// <param name="splitter"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static Boolean ListToString(List<String> strlist, char splitter, out String result)
        {
            result = String.Empty;
            if ((strlist == null || strlist.Count < 1))
            {
                return false;
            }

            foreach (String item in strlist)
            {
                result = result + item + splitter;
            }

            result = result.Remove(result.Length - 1, 1);
            return true;
        }


        ///// <summary>
        ///// 使用指定间隔符,把字符串分割为多个子串,合并为BindingList
        ///// </summary>
        ///// <param name="rawdata"></param>
        ///// <param name="splitter"></param>
        ///// <param name="strlist"></param>
        ///// <returns></returns>
        //public static Boolean StringToBindingList(String rawdata, char splitter, out ObservableCollection<String> strlist)
        //{
        //    strlist = new ObservableCollection<string>();
        //    if (String.IsNullOrEmpty(rawdata))
        //    {
        //        return false;
        //    }

        //    String[] ary = rawdata.Split(splitter);
        //    if ((ary == null) || (ary.Length < 1))
        //    {
        //        return false;
        //    }

        //    for (int i = 0; i < ary.Length; i++)
        //    {
        //        strlist.Add(ary[i]);
        //    }
        //    return true;
        //}

        ///// <summary>
        ///// 使用指定间隔符,把BindingList合并为一个字符串
        ///// </summary>
        ///// <param name="strlist"></param>
        ///// <param name="splitter"></param>
        ///// <param name="result"></param>
        ///// <returns></returns>
        //public static Boolean BindingListToString(ObservableCollection<String> strlist, char splitter, out String result)
        //{
        //    result = String.Empty;
        //    if ((strlist == null || strlist.Count < 1))
        //    {
        //        return false;
        //    }

        //    StringBuilder tmpstr = new StringBuilder(4096);
        //    foreach (String item in strlist)
        //    {
        //        tmpstr.Append(item);
        //        tmpstr.Append(splitter);
        //    }

        //    tmpstr.Remove(result.Length - 1, 1);
        //    result = tmpstr.ToString();
        //    return true;
        //}

        /// <summary>
        /// 使用指定间隔符,把字符串分割为多个子串,合并为List
        /// </summary>
        /// <param name="rawdata"></param>
        /// <param name="splitter"></param>
        /// <param name="strlist"></param>
        /// <returns></returns>
        public static Boolean StringToIntList(String rawdata, char splitter, ref List<Int32> intlist)
        {
            List<String> strlst = null;
            Boolean bl = StringToList(rawdata, splitter, ref strlst);
            if (!bl)
            {
                return false;
            }

            intlist = new List<int>();
            Int32 val;
            for (int i = 0; i < strlst.Count; i++)
            {
                bl = Int32.TryParse(strlst[i], out val);
                if (bl)
                {
                    intlist.Add(val);
                }
            }

            return (intlist.Count > 0);
        }

        /// <summary>
        /// 使用指定间隔符,把字符串分割为多个子串,合并为List
        /// </summary>
        /// <param name="rawdata"></param>
        /// <param name="splitter"></param>
        /// <param name="strlist"></param>
        /// <returns></returns>
        public static Boolean StringToList(String rawdata, char splitter, ref List<String> strlist)
        {
            if (String.IsNullOrEmpty(rawdata))
            {
                return false;
            }

            String[] ary = rawdata.Split(splitter);
            if ((ary == null) || (ary.Length < 1))
            {
                return false;
            }

            if (strlist == null)
            {
                strlist = new List<string>();
            }
            strlist.AddRange(ary);
            return true;
        }

        /// <summary>
        /// 把字符串列表转换为Boolean数组
        /// </summary>
        /// <param name="boolliststr"></param>
        /// <param name="boolary"></param>
        /// <returns></returns>
        public static Boolean StringToBooleanArray(String boolliststr, ref Boolean[] boolary)
        {
            if (boolary == null)
            {
                return false;
            }

            Int32 len = (boolliststr.Length > boolary.Length) ? boolary.Length : boolliststr.Length;
            for (Int32 idx = 0; idx < len; ++idx)
            {
                boolary[idx] = (boolliststr[idx] == '0') ? false : true;
            }

            return true;
        }

        /// <summary>
        /// 把Boolean数组转换为字符串列表
        /// </summary>
        /// <param name="boolary"></param>
        /// <param name="boolliststr"></param>
        /// <returns></returns>
        public static String BooleanArrayToString(Boolean[] boolary)
        {
            if (boolary == null)
            {
                return String.Empty;
            }
            String boolliststr = String.Empty;
            String itemstr = String.Empty;
            foreach (Boolean bl in boolary)
            {
                itemstr = bl ? "1" : "0";
                boolliststr = boolliststr + itemstr;
            }

            return boolliststr;
        }

        /// <summary>
        /// 把Boolean数组转换为数值数组
        /// </summary>
        /// <param name="boolary"></param>
        /// <param name="intarray"></param>
        /// <returns></returns>
        public static Boolean BooleanArrayToInt32Array(Boolean[] boolary, Int32[] intarray)
        {
            if (boolary == null || intarray == null ||
                boolary.Length < 1 || intarray.Length < 1 || boolary.Length != intarray.Length)
            {
                return false;
            }

            for (Int32 idx = 0; idx < intarray.Length; ++idx)
            {
                intarray[idx] = boolary[idx] ? 1 : 0;
            }
            return true;
        }

        /// <summary>
        /// 把Boolean数组转换为数值数组
        /// </summary>
        /// <param name="boolary"></param>
        /// <param name="intarray"></param>
        /// <returns></returns>
        public static Int32[] BooleanArrayToInt32Array(Boolean[] boolary)
        {
            if (boolary == null || boolary.Length < 1)
            {
                return null;
            }

            Int32[] intarray = new Int32[boolary.Length];
            for (Int32 idx = 0; idx < boolary.Length; ++idx)
            {
                intarray[idx] = boolary[idx] ? 1 : 0;
            }
            return intarray;
        }

        /// <summary>
        /// 把Boolean数组转换为数值数组
        /// </summary>
        /// <param name="boolary"></param>
        /// <param name="intarray"></param>
        /// <returns></returns>
        public static Boolean Int32ArrayToBooleanArray(Int32[] intarray, Boolean[] boolary)
        {
            if (boolary == null || intarray == null ||
                boolary.Length < 1 || intarray.Length < 1 || boolary.Length != intarray.Length)
            {
                return false;
            }

            for (Int32 idx = 0; idx < intarray.Length; ++idx)
            {
                boolary[idx] = (intarray[idx] == 0) ? false : true;
            }
            return true;
        }


        /// <summary>
        /// 把Boolean数组转换为数值数组
        /// </summary>
        /// <param name="boolary"></param>
        /// <param name="intarray"></param>
        /// <returns></returns>
        public static Boolean[] Int32ArrayToBooleanArray(Int32[] intarray)
        {
            if (intarray == null || intarray.Length < 1)
            {
                return null;
            }
            Boolean[] boolary = new Boolean[intarray.Length];
            for (Int32 idx = 0; idx < intarray.Length; ++idx)
            {
                boolary[idx] = (intarray[idx] == 0) ? false : true;
            }
            return boolary;
        }

        /// <summary>
        /// 字节转换为Int16
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Int32 BytesToInt16(Byte[] bytes)
        {
            if (bytes == null || bytes.Length < 2)
            {
                return 0;
            }
            Int32 ret = bytes[0] + (bytes[1] << 8);
            return ret;
        }

        /// <summary>
        /// 字节转换为Int16
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Int32 BytesToInt16(Byte[] bytes, Int32 startidx)
        {
            if (bytes == null || startidx < 0 || startidx + 2 > bytes.Length)
            {
                return 0;
            }
            Int32 ret = bytes[startidx] + (bytes[startidx + 1] << 8);
            return ret;
        }

        /// <summary>
        /// 字节转换为Int32
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Int32 BytesToInt32(Byte[] bytes)
        {
            if (bytes == null || bytes.Length < 4)
            {
                return 0;
            }
            Int32 ret = bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24);
            return ret;
        }

        /// <summary>
        /// 字节转换为Int32
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static Int32 BytesToInt32(Byte[] bytes, Int32 startidx)
        {
            if (bytes == null || startidx < 0 || startidx + 4 > bytes.Length)
            {
                return 0;
            }
            Int32 ret = bytes[startidx] +
                (bytes[startidx + 1] << 8) +
                (bytes[startidx + 2] << 16) +
                (bytes[startidx + 3] << 24);
            return ret;
        }

    }
}
